package com.androidme.app.framework.base;


import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.media.MediaPlayer;
import android.media.SoundPool;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Window;
import com.androidme.app.framework.util.DialogUtil;
import roboguice.activity.RoboActivity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;


public abstract class AndroidMeActivity extends RoboActivity {
    /**
     * message's what
     */
    public static final int SHOW_PROGRESS_BAR = 1;
    public static final int REMOVE_PROGRESS_BAR = SHOW_PROGRESS_BAR + 1;
    public static final int REFRESH = REMOVE_PROGRESS_BAR + 1;
    /**
     * music & sound
     */
    protected static MediaPlayer mediaPlayer;
    protected static SoundPool soundPool;
    protected static HashMap<Integer, Integer> soundPoolMap = new HashMap<Integer, Integer>();
    /**
     * for load layout from xml
     */
    protected static LayoutInflater layoutInflater;

    public static AndroidMeApplication application;

    /**
     * flag showing wheather data has been loaded
     */
    private boolean hasPrepareDate = false;
    /**
     * flag showing  weather data need to be reloaded
     */
    private boolean needRePrepareData = false;
    /**
     * current active thread number
     */
    private volatile int activeThreadNum = 0;
    /**
     * save all bmp class used in current activity
     */
    private volatile List<Bitmap> bitmapList = new ArrayList<Bitmap>(0);


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("androidme lifecycle create:", getClass().getName());

        if (layoutInflater == null) {
            layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        }

        if (application == null) {
            application = (AndroidMeApplication) getApplication();
            application.setActiveContext(getClass().getCanonicalName(), this);
        }

        setContentView();
        initSound();
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d("androidme lifecycle start:", getClass().getName());
        application.setActiveContext(getClass().getCanonicalName(), this);
        if (!hasPrepareDate) {
            onPrepareData();
            hasPrepareDate = true;
        } else if (needRePrepareData) {
            onPrepareData();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("androidme lifecycle resume:", getClass().getName());
        application.setActiveContext(getClass().getCanonicalName(), this);
        if (application.getBackgroundMusic() > 0 && mediaPlayer == null) {
            mediaPlayer = MediaPlayer.create(this, application.getBackgroundMusic());
            mediaPlayer.setLooping(true);
        }

        if (mediaPlayer != null) {
            mediaPlayer.start();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d("androidme lifecycle pause:", getClass().getName());
        application.resetActiveContext(getClass().getCanonicalName());
        if (mediaPlayer != null) {
            mediaPlayer.pause();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("androidme lifecycle stop:", getClass().getName());
        application.resetActiveContext(getClass().getCanonicalName());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("androidme lifecycle destroy:", getClass().getName());
        application.resetActiveContext(getClass().getCanonicalName());
        if (bitmapList != null && bitmapList.size() > 0) {
            for (Bitmap bitmap : bitmapList) {
                if (!bitmap.isRecycled()) {
                    bitmap.recycle();
                }
            }

            bitmapList.clear();
        }
    }

    public int getWindowFeatures() {
        Window window = getWindow();
        if (window == null) {
            return 0;
        }
        try {
            return 0;
        } catch (Exception e) {
            return 0;
        }
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case SHOW_PROGRESS_BAR:
                    DialogUtil.showProgressBar(AndroidMeActivity.this);
                    break;
                case REMOVE_PROGRESS_BAR:
                    DialogUtil.hideProgressBar();
                    break;
                case REFRESH:
                    onRefresh();
                    break;

            }
        }
    };

    private void setContentView() {
        Log.v(getClass().getName(), "Class Name " + getClass().getSimpleName());
        String mClassName = getClass().getSimpleName();
        int end = mClassName.length() - 8;
        int mLayoutResId = getResources().getIdentifier(mClassName.toLowerCase(Locale.ENGLISH).substring(0, end), "layout", getPackageName());
        try {
            setContentView(mLayoutResId);
        } catch (Exception e) {
            Log.v(getClass().getName(), "No Layout Resource!");
        }
    }


    protected void doAsync(Runnable command) {
        doAsync(command, false);
    }

    protected void doAsync(Runnable command, boolean important) {
        if (important) {
            application.getCoreThreadPool().execute(command);
        } else {
            application.getCommonThreadPool().execute(command);
        }
    }

    protected void doAsync(final Runnable command, String title, String message) {
        doAsync(command, title, message, false);
    }

    protected void doAsync(final Runnable command, String title, String message, final boolean important) {
        new AlertDialog.Builder(this)
                .setIcon(android.R.drawable.ic_dialog_info)
                .setTitle(title)
                .setMessage(message)
                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        doAsync(command, important);
                    }
                }).setNegativeButton(android.R.string.cancel, null)
                .show();
    }

    public void showProgressBar() {
        activeThreadNum++;
        handler.sendMessage(handler.obtainMessage(SHOW_PROGRESS_BAR));
    }

    public void removeProgressBar() {
        activeThreadNum--;
        if(activeThreadNum<=0){
            handler.sendMessage(handler.obtainMessage(REMOVE_PROGRESS_BAR));
        }
    }

    public void refresh() {
        handler.sendMessage(handler.obtainMessage(REFRESH));
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
    }

    private void putSoundPool(int resId) {
        soundPoolMap.put(resId, soundPool.load(this, resId, 1));
    }

    public static void playSoundPool(int resId, float volume) {
        soundPool.play(soundPoolMap.get(resId), volume, volume, 1, 0, 1F);
    }

    protected abstract void onPrepareData();

    protected abstract void onRefresh();

    protected void initSound() {
    }

    public boolean isLandscapeMode() {
        return getWindowManager().getDefaultDisplay().getOrientation() == 1;
    }

    public boolean isPortraitMode() {
        return !isLandscapeMode();
    }

    public void setNeedRePrepareData(boolean needRePrepareData) {
        this.needRePrepareData = needRePrepareData;
    }

    protected void addBitmap(Bitmap bitmap) {
        if (bitmapList != null) {
            bitmapList.add(bitmap);
        }
    }
}
